package pl.model.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.springframework.orm.jpa.JpaCallback;
import org.springframework.transaction.annotation.Transactional;

import pl.model.dao.BookDao;
import pl.model.domain.Book;

@Transactional
public class JpaBookDao extends JpaAbstractDao<Book> implements BookDao {

	@Override
	public Book findWithAuthor(final Integer bookId) {
		return  (Book) getJpaTemplate().execute(new JpaCallback(){
			public Object doInJpa(EntityManager em) throws PersistenceException {
                                log.debug("findWithAuthor " + bookId);
				return em.createQuery("FROM Book b LEFT JOIN FETCH b.author WHERE b.id = :id")
						.setParameter("id", bookId).getSingleResult();
			}
			
		});
	}

	@Override
	public List<Book> getAllSortedByTags() {
		List<Book> books = (List<Book>) getJpaTemplate().execute(new JpaCallback(){

			@Override
			public Object doInJpa(EntityManager em)
					throws PersistenceException {
				Query q = em.createQuery("from Book b");
				
				List l =q.getResultList();
				return l;
			}
			
		});
		return books;
	}

	@Override
	public List<Book> findByTitle(final String title) {
		List<Book> books = (List<Book>) getJpaTemplate().execute(new JpaCallback(){

			@Override
			public Object doInJpa(EntityManager em)
					throws PersistenceException {
				Query q = em.createQuery("from Book b where b.title like :title")
					.setParameter("title", title);
				
				List l =q.getResultList();
				return l;
			}
			
		});
		return books;
	}

	@Override
	public List<Book> findByDescription(final String description) {
		List<Book> books = (List<Book>) getJpaTemplate().execute(new JpaCallback(){

			@Override
			public Object doInJpa(EntityManager em)
					throws PersistenceException {
				Query q = em.createQuery("from Book b where b.description like :description")
					.setParameter("description", description);
				
				List l =q.getResultList();
				return l;
			}
			
		});
		return books;
	}

	
}
